Imports System.Runtime.InteropServices

Namespace Timers

    Module mTimers

        Public Structure Timer
            Dim Name As String
            Dim Ticker As Long
            Dim Interval As Long
            Dim Value As Integer
            Dim MaxVal As Integer
            Dim NoLoop As Boolean
        End Structure

        Public mTimer As New List(Of Timer)

        Public Sub AddTimer(ByRef Name As String, ByRef Interval As Long, ByRef MaxVal As Integer, Optional ByRef noloop As Boolean = False, Optional ByRef start As Integer = 0)


            If TimerIndex(Name) = -1 Then

                Dim tmp As New Timer
                tmp.Name = Name
                tmp.Interval = Interval
                tmp.MaxVal = MaxVal
                tmp.Ticker = Date.Now.Ticks + tmp.Interval
                tmp.Value = start
                tmp.NoLoop = noloop

                mTimer.Add(tmp)

            Else
                Throw New Exception("Timer '" & Name & "' already exists!")
            End If


        End Sub

        Public Sub RemoveTimer(ByRef Name As String)
retry:
            If TimerIndex(Name) > -1 Then
                mTimer.RemoveAt(TimerIndex(Name))
            End If

        End Sub

        Public Sub RemoveAllTimers()

            mTimer.Clear()

        End Sub

        Public Function GetTimer(ByRef Name As String) As Integer

            If TimerIndex(Name) > -1 Then
                Return CType(mTimer.Item(TimerIndex(Name)), Timer).Value
            End If

        End Function

        Public Function GetTick(ByRef Name As String) As Long
            If TimerIndex(Name) > -1 Then
                Return CType(mTimer.Item(TimerIndex(Name)), Timer).Ticker
            End If
        End Function

        Public Sub SetTick(ByRef Name As String, ByRef tick As Long)
            If TimerIndex(Name) > -1 Then
                Dim tmr As Timer = mTimer.Item(TimerIndex(Name))
                tmr.Ticker = tick
                mTimer.RemoveAt(TimerIndex(Name))
                mTimer.Add(tmr)
            End If
        End Sub

        Private Function TimerIndex(ByRef name As String) As Integer

            For i As Integer = 0 To mTimer.Count - 1
                If mTimer.Item(i).Name = name Then
                    Return i
                End If
            Next

            Return -1

        End Function

        Public Sub DoTimers()

            If mTimer.Count = 0 Then Exit Sub

            Dim now As Long = Date.Now.Ticks
            Dim t As Timer

            'SyncLock mTimer

            Dim c As Integer = mTimer.Count - 1
            For i As Integer = 0 To c

                If mTimer.Item(i).Ticker <= now And mTimer.Item(i).Value <= mTimer.Item(i).MaxVal Then

                    t = mTimer.Item(i)

                    t.Ticker += t.Interval
                    t.Value += 1
                    If t.Value > t.MaxVal Then
                        If t.NoLoop Then
                            t.Value -= 1
                        Else
                            t.Value = 0
                        End If
                    End If

                    mTimer.Item(i) = t

                End If

            Next

            'End SyncLock

        End Sub

    End Module

End Namespace
